/* $RCSFile: SettingsDictionary.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/Configuration/Settings/SettingsDictionary.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:27  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.Caching;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using AddonNice.Diagnostics;
using AddonNice.UI;
using AddonNice.UI.WebControls;
using AddonNice.Settings;

using Path2     =   AddonNice.Settings.Path;
using Cache2    =   AddonNice.Settings.Cache.CurrentCache;
using Key2      =   AddonNice.Settings.Cache.Key;

namespace AddonNice.Configuration
{
    public enum SettingsStatus { Empty, Loading, Loaded, Error };

    /// <summary>
    /// Special dictionary for SettingsItems based on a generic to allow typing
    /// </summary>
    public class SettingsDictionary : Dictionary<string, SettingItem>
    {
        public SettingsStatus   Status  =   SettingsStatus.Empty;

        DateTime _ADNCreationDate    =   DateTime.UtcNow;

        // Used inernally fro cache management in someoccasions
        public DateTime ADNCreationDate
        {
            get
            {
                return _ADNCreationDate;
            }
        }

        public SettingsDictionary()
        {}


        /// <summary>
        /// Build a list of items with those with dependency first in order to respect the order changes will apply
        /// </summary>
        /// <returns></returns>
        public List<SettingItem> CreateDependencyList()
        {
            List<SettingItem> ApplyQ    =   new List<SettingItem>();
            // first pass to add in first place items with dependancies
            foreach (KeyValuePair<string, SettingItem> pair in this)
            {
                SettingItem st = pair.Value;
                if (st.DependentItems.Count > 0)
                {
                    int idx = int.MaxValue;
                    foreach (SettingItem std in st.DependentItems)
                    {
                        int idx2 = int.MaxValue;
                        if (ApplyQ.Contains(std))
                            idx2 = ApplyQ.IndexOf(std);
                        if (idx2 < idx)
                            idx = idx2;
                    }
                    if (idx < int.MaxValue)
                        ApplyQ.Insert(idx, st);
                    else ApplyQ.Add(st);
                }
            }
            // secdond pass, all depending or without dependancy items
            foreach (KeyValuePair<string, SettingItem> pair in this)
            {
                SettingItem st = pair.Value;
                if (ApplyQ.Contains(st))
                    continue;
                ApplyQ.Add(st);
            }
            return ApplyQ;
        }

        public virtual void AddUpper(string key, SettingItem value)
        {
            Add(key.ToUpper(), value);
        }

        /// <summary>
        /// Uses the SettingItem.Key as key
        /// </summary>
        public virtual void AddSetting(SettingItem value)
        {
            Add(value.Key, value);
        }

        /// <summary>
        /// Return true if this key exist in generic settings dictionary 
        /// </summary>
        /// <param name="key">key to search for</param>
        /// <returns></returns>
        public bool ContainsUpperKey(string key)
        {
            string k = key.ToUpper();
            return ContainsKey(k);
        }
        /// <summary>
        /// Return true if this key exist in generic settings dictionary 
        /// </summary>
        /// <param name="key">key to search for</param>
        /// <returns></returns>
        public bool ContainsKeyNotEmpty(string key)
        {
            string k = key.ToUpper();
            return (ContainsKey(k) && !string.IsNullOrEmpty(this[k].Value));
        }

        /// <summary>
        /// Returns true if this key exists and has a bool value of true
        /// else returns false
        /// </summary>
        /// <param name="key">key to search for</param>
        /// <returns></returns>
        public bool IsOkKey(string key)
        {
            string k = key.ToUpper();
            if (ContainsKey(k))
            {
                string strv = this[k].Value;
                if (!string.IsNullOrEmpty(strv) && bool.Parse(strv))
                    return true;
            }
            return false;
        }
        public bool StringValue(string key, ref string val)
        {
            string k = key.ToUpper();
            if (ContainsKey(k))
            {
                string strv = this[k].Value.Trim();
                if (!string.IsNullOrEmpty(strv))
                {
                    val = strv;
                    return true;
                }
            }
            return false;
        }
        
        public bool IntValue(string key, ref int val)
        {
            string k = key.ToUpper();
            if (ContainsKey(k))
            {
                int v = this[k].ToInt();
                if ( v != 0 )
                {
                    val = v;
                    return true;
                }
            }
            return false;
        }
    }
}
